perm filename SEG2.SAI[SYS,HE]1 blob sn#016522 filedate 1972-12-06 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00012 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00002 00002	ENTRY	DUMMY
 00003 00003	α	GENSYM,ONLINE
 00007 00004	α	XPOINT
 00009 00005	α	ADDLINE
 00012 00006	α	ADDEL
 00015 00007	α	EXTEND
 00019 00008	α	EXT_LINE
 00021 00009	α	EXT_FACE
 00023 00010	α	ADDCORNER
 00028 00011	α	ADDFACE
 00032 00012	α	CLEAN
 00033 ENDMK
⊗;
ENTRY	DUMMY;

BEGIN "SEG2"

REQUIRE	100		PNAMES;
REQUIRE	100		NEW_ITEMS;
REQUIRE	"PREAMB.SAI[SYS,HE]"	SOURCE_FILE;
REQUIRE	"SYMBOL.AUX[H,RPO]"	SOURCE_FILE;
REQUIRE	"SEGDPY.HDR[SYS,HE]"	SOURCE_FILE;
REQUIRE	"SEGCOM.AUX[SYS,HE]"	SOURCE_FILE;


INTEGER FLAG;


α EXTERNALS;
EBP	COLINEAR(ITEMVAR L1,L2);
ERP	DIST(SAFE REAL ARRAY ITEMVAR P1,P2);
EBP	PARALLEL(ITEMVAR L1,L2);
ESP	PRINTNAME(ITEMVAR X);
EBP	VERT(ITEMVAR L2);
α	GENSYM,ONLINE;

INTERNAL STRING PROCEDURE GENSYM(INTEGER ITEMVAR X);
BEGIN "GENSYM"
	STRING NAME;
	NAME←PRINTNAME(X);
	IF FLAG
	THEN BEGIN
		TYPE "GENSYM - PRINTNAME LOSSAGE" EOM;
		CALL(0,"EXIT");
		END;
	RETURN(NAME&CVS(∂(X)←∂(X)+1));
	END "GENSYM";

α	ONLINE
returns true if the given point would lie on the given
line, if extended;

INTERNAL BOOLEAN PROCEDURE ONLINE(ITEMVAR L;SAFE REAL ARRAY ITEMVAR P);
BEGIN "ONLINE"
	REAL A,B,C,D,ANS;
	SET SE;
	SAFE REAL ARRAY ITEMVAR PA,PB;
	DEFINE
		XX(Z)=<∂(Z)[1]>,
		YY(Z)=<∂(Z)[2]>,
		EQUATION(Z)=<ABS(A*XX(Z) + B*YY(Z) +C)>;

SE←ENDPT⊗L;
PA←LOP(SE);
PB←COP(SE);
A←YY(PA)-YY(PB);
B←XX(PB)-XX(PA);
D←SQRT(A↑2 + B↑2);
A←A/D;
B←B/D;
C← - A*XX(PA) - B*YY(PA);
IF (ANS←EQUATION(P))<3.0
THEN BEGIN TYPE "ONLINE - "&PRINTNAME(L)&
	","&PRINTNAME(P)&" TRUE"&CVG(ANS) EOM; RETURN(TRUE); END
ELSE BEGIN TYPE "ONLINE - "&PRINTNAME(L)&
	","&PRINTNAME(P)&" FALSE"&CVG(ANS) EOM; RETURN(FALSE); END;
END "ONLINE";

α	XPOINT
finds the image intersection point of two lines:
parallel to L1 and through P1 & parallel to L2 and thru P2.;

INTERNAL SAFE REAL ARRAY ITEMVAR PROCEDURE
	XPOINT(REAL ITEMVAR L1;SAFE REAL ARRAY ITEMVAR P1;
		REAL ITEMVAR L2;SAFE REAL ARRAY ITEMVAR P2);
BEGIN "XPOINT"
	  SAFE REAL ARRAY ITEMVAR X,Y,Z,W;
	SET S;
	STRING STR;
	REAL A1,B1,C1,A2,B2,C2,D,CONST;

S←ENDPT⊗L1;
X←LOP(S);
Y←COP(S);
S←ENDPT⊗L2;
Z←LOP(S);
W←COP(S);

A1←∂(X)[2]-∂(Y)[2];
B1←∂(Y)[1]-∂(X)[1];
D←SQRT(A1↑2 + B1↑2);
A1←A1/D;
B1←B1/D;
C1←-(A1*∂(P1)[1])-(B1*∂(P1)[2]);

A2←∂(Z)[2]-∂(W)[2];
B2←∂(W)[1]-∂(Z)[1];
D←SQRT(A2↑2 + B2↑2);
A2←A2/D;
B2←B2/D;
C2←-(A2*∂(P2)[1])-(B2*∂(P2)[2]);

CONST← (A2*C1-C2*A1)/(A1*B2-A2*B1);

X←NEW(SIZE7);
NEW_PNAME(X,GENSYM(NEWP));

∂(X)[1]←-(B1/A1)*CONST - C1/A1;
∂(X)[2]←CONST;

DPYVI(X);

RETURN (X);

END "XPOINT";


α	ADDLINE
heuristic line proposer for individual bodies;

INTERNAL BOOLEAN PROCEDURE ADDLINE(ITEMVAR B);
BEGIN "ADDLINE"
INTEGER I;
SAFE REAL ARRAY ITEMVAR PX,P1;
REAL ITEMVAR LX,L1,L2,L3,L4,L;
ITEMVAR P,R,F;
SET ITEMVAR BS;
SET S1,S2;
STRING STR;
BOOLEAN BOOL;

TYPE "ADDLINE - ENTERED" EOM;
ASSIGN BS|EXTERIOR⊗B≡BS HOLDS;
∀ P|POINT⊗B≡P DO
IF FLAVOR⊗P≡BADL ∧ (∂(BS)∩ENDPT`P = PHI) ∧ (LENGTH(ENDPT`P∩LINE⊗B)=2)
THEN BEGIN "BADL"
	S1←CORNER`P∩FACE⊗B;
	∀ R|RεS1 ∧ (LENGTH(BOUNDARY⊗R)≠4) DO
	 ∀ P1|CORNER⊗R≡P1 ∧ (P1≠P) ∧ (LENGTH(ENDPT`P1∩LINE⊗B)=2) ∧
		(ENDPT`P∩LINE⊗B∩ENDPT`P1=PHI) DO
	 BEGIN "BADL1"
		S2←ENDPT`P∩LINE⊗B;
		L1←LOP(S2);
		L2←COP(S2);
		S2←ENDPT`P1∩LINE⊗B;
		L3←LOP(S2);
		L4←COP(S2);
		IF (PARALLEL(L1,L3)∧PARALLEL(L2,L4))∨
		   (PARALLEL(L1,L4)∧PARALLEL(L2,L3)) ∧
		  ((ENDPT⊗L1∪ENDPT⊗L2)∩(ENDPT⊗L3∪ENDPT⊗L4)=PHI)
		THEN BEGIN "BADL2"
			TYPE TAB&"BADL ADD-A-LINE" EOM;
			L←NEW(0.0);NEW_PNAME(L,GENSYM(NEWL));
			MAKE LINE⊗B≡L;
			F←NEW(SIZE4);NEW_PNAME(F,GENSYM(NEWF));
			MAKE FACE⊗B≡F;
			MAKE ENDPT⊗L≡P;
			MAKE ENDPT⊗L≡P1;
			MAKE BOUNDARY⊗F≡L;
			MAKE BOUNDARY⊗R≡L;
			MAKE CORNER⊗F≡P;
			MAKE CORNER⊗F≡P1;
			LX←COP(ENDPT`P∩LINE⊗B-{L});
			PX←COP(ENDPT⊗LX-{P});
			WHILE PX≠P1 DO
			BEGIN "BADL3"
				ERASE BOUNDARY⊗R≡LX;
				ERASE CORNER⊗R≡PX;
				MAKE BOUNDARY⊗F≡LX;
				MAKE CORNER⊗F≡PX;
				LX←COP(ENDPT`PX∩BOUNDARY⊗R);
				PX←COP(ENDPT⊗LX-{PX});
				END "BADL3";
			ERASE BOUNDARY⊗R≡LX;
			MAKE BOUNDARY⊗F≡LX;
			S1←S2←PHI;
			RETURN(TRUE);
			END "BADL2";
		END "BADL1";
	END "BADL";
S1←S2←PHI;
TYPE TAB&"NOTHING HAPPENED" EOM;
RETURN(FALSE);
END "ADDLINE";

α	ADDEL
pick up a face that is not complete:  one vertex is endpt for only one
line of the face.
look for one corner with only one line and a corner opposite it with ≥ two lines.
find the intersection point of the one line vertex with a line parallel
to the line of the face at the other vertex of the single line. (?)
			LA
 intersection →	*   p1....pa
    point      		/|
		      L/ |
		      /  |
          p2....LB.../pb
	    |        |
	    |	     |
This won't work for LBEAMs due to the ≤4 test on the corners...
work that out later.
;
INTERNAL BOOLEAN PROCEDURE ADDEL(ITEMVAR B);
BEGIN "ADDEL"
ITEMVAR F,L,LA,LB,LY;
SET ITEMVAR BS;
SAFE REAL ARRAY ITEMVAR P1,P2,P,PA,PB,PY;
TYPE "ADDEL - ENTERED" EOM;
∀ F|FACE⊗B≡F DO
 ∀ P1|	CORNER⊗F≡P1 ∧ POINT⊗B≡P1 ∧
	(LENGTH(ENDPT`P1 ∩ LINE⊗B)=1) DO
IF LENGTH(CORNER⊗F)≤4
THEN BEGIN "ADDEL1"
	ASSIGN LA|BOUNDARY⊗F≡LA ∧ ENDPT⊗LA≡P1 HOLDS;
	ASSIGN LB|BOUNDARY⊗F≡LB ∧ (LA≠LB) ∧ (PARALLEL(LA,LB)) HOLDS;
	ASSIGN L|	BOUNDARY⊗F≡L ∧ (L≠LA) ∧ (L≠LB) ∧
			ADJ(L,LA) ∧ ADJ(L,LB) HOLDS;
	PA←COP(ENDPT⊗LA ∩ ENDPT⊗L);
	PB←COP(ENDPT⊗LB ∩ ENDPT⊗L);
	P2←COP(ENDPT⊗LB - {PB});
	IF FLAVOR⊗P2≡TJOINT
	THEN BEGIN
		TYPE TAB&"TJOINT RETURN" EOM;
		RETURN(FALSE);
		END;

	TYPE TAB&"FACE POINTS:"&PRINTNAME(P1)&", "&PRINTNAME(P2) EOM;
	PY←XPOINT(LA,PA,L,P2);
	LY←NEW(0.0);NEW_PNAME(LY,GENSYM(NEWL));
	ERASE POINT⊗B≡P1;
	MAKE POINT⊗B≡PY;
	MAKE LINE⊗B≡LY;
	MAKE ENDPT⊗LY≡PY;
	MAKE ENDPT⊗LY≡P2;
	MAKE BOUNDARY⊗F≡LY;
	ERASE CORNER⊗F≡P1;
	MAKE CORNER⊗F≡PY;

	ERASE ENDPT⊗LA≡P1;
	MAKE ENDPT⊗LA≡PY;
	ASSIGN BS|EXTERIOR⊗B≡BS HOLDS;
	PUT LY IN ∂(BS);
	RETURN (TRUE);
	END "ADDEL1";
TYPE TAB&"NOTHING HAPPENED" EOM;
RETURN(FALSE);
END "ADDEL";

α	EXTEND
This procedure is intended to "scan" the structural representation
for body B and detect any colinear disjoint segments which should
be joined.  The body representation is updated accordingly.
Quite a bit of fiddling around is necessary due to the fact that
it is not too easy using our description to determine the right and
left hand regions of a directed line.

     V1	o--------
	|
 	| L1
 	|
    V2	o

    V3	o
	|
	| L2
    V4	o--------;

INTERNAL BOOLEAN PROCEDURE EXTEND(ITEMVAR B);
BEGIN "EXTEND"
	SAFE REAL ARRAY VP1,VV1,VP2,VV2[1:2];
	REAL VP1XVV1,VP2XVV2;
	SET SU,SV,SW,SX;
	SET ITEMVAR XS;
	ITEMVAR L,L1,L2,R1,R2,R3,R4,F,P;
	INTEGER I,J;
	SAFE REAL ARRAY ITEMVAR U,V,P1,P2,V1,V2,V3,V4;

TYPE "EXTEND - ENTERED" EOM;
∀ F|FACE⊗B≡F DO
BEGIN "EXT1"
  SV←PHI;
  ∀ P|CORNER⊗F≡P DO
  IF LENGTH(ENDPT`P)=1
  THEN PUT P IN SV;

IF LENGTH(SV)≥2
THEN ∀ P1,P2| P1εSV ∧ P2εSV ∧ (P1≠P2) DO
BEGIN "EXT2"
  ASSIGN L1|ENDPT⊗L1≡P1 HOLDS;
  ASSIGN L2|ENDPT⊗L2≡P2 HOLDS;
  TYPE TAB&"CONSIDERING "&PRINTNAME(L1)&"  "&PRINTNAME(L2) EOM;
  IF COLINEAR(L1,L2)
  THEN BEGIN "CEXT"
	SW←ENDPT⊗L1;
	SX←ENDPT⊗L2;
	V1←LOP(SW);
	V2←COP(SW);
	V3←LOP(SX);
	V4←COP(SX);

	IF DIST(V1,V3)<DIST(V2,V3)
	THEN V2↔V1;
	IF DIST(V4,V2)<DIST(V3,V2)
	THEN V3↔V4;

ASSIGN XS|EXTERIOR⊗B≡XS HOLDS;
IF L2ε∂(XS)
THEN REMOVE L2 FROM ∂(XS);
α ...this shouldn't be necessary ...;
IF ¬L1ε∂(XS)
THEN PUT L1 IN ∂(XS);
	ERASE LINE⊗B≡L2;
	ERASE POINT⊗B≡V2;
	ERASE POINT⊗B≡V3;
	ERASE ENDPT⊗L2≡V3;
	ERASE ENDPT⊗L2≡V4;
	ERASE ENDPT⊗L1≡V2;
	ERASE BOUNDARY⊗ANY≡L2;
	ERASE CORNER⊗ANY≡V2;
	ERASE CORNER⊗ANY≡V3;

	MAKE ENDPT⊗L1≡V4;

	IF TJOINT⊗B≡L2
	THEN BEGIN
		ERASE TJOINT⊗B≡L2;
		MAKE TJOINT⊗B≡L1;
		END;

	MAKE TPAIR⊗L1≡L2;
	MAKE TPAIR⊗L2≡L1;
	RETURN(TRUE);
	END "CEXT";
  END "EXT2";
END "EXT1";

TYPE TAB&"NOTHING HAPPENED" EOM;
RETURN (FALSE);
END "EXTEND";

α	EXT_LINE
this procedure extends a line segment to a corner;

INTERNAL BOOLEAN PROCEDURE EXT_LINE(ITEMVAR B);
BEGIN "EXT LINE"
ITEMVAR F,L;
SAFE REAL ARRAY ITEMVAR P1,P2;
TYPE "EXT_LINE - ENTERED" EOM;
∀ F|FACE⊗B≡F DO
 ∀ P1|	CORNER⊗F≡P1 ∧ POINT⊗B≡P1 ∧ (LENGTH(ENDPT`P1 ∩ LINE⊗B)=1) DO
IF LENGTH(CORNER⊗F)=5
THEN BEGIN "ELONE"
	ASSIGN L|BOUNDARY⊗F≡L ∧ ENDPT⊗L≡P1 HOLDS;
	∀ P2|	CORNER⊗F≡P2 ∧ POINT⊗B≡P2 ∧
		(¬(ENDPT⊗L≡P2)) ∧ (LENGTH(ENDPT`P2 ∩ LINE⊗B)=2) DO
	IF ONLINE(L,P2)
	THEN BEGIN "ELTWO"
		TYPE TAB&"LINE "&PRINTNAME(L)&
		   " EXTENDED TO POINT "&PRINTNAME(P2) EOM;
		ERASE ENDPT⊗L≡P1;
		MAKE ENDPT⊗L≡P2;
		ERASE CORNER⊗F≡P1;
		ERASE POINT⊗B≡P1;
		RETURN(TRUE);
		END "ELTWO";
	END "ELONE";
TYPE TAB&"NOTHING HAPPENED" EOM;
RETURN(FALSE);
END "EXT LINE";

α	EXT_FACE
this procedure will take care of the case where a face
is cut off by a foreground body.  If the truncated face
boundaries are vertical, then the height is known (using
formula from FINDEDGELENGTHS in the RECOGNIZER).;

INTERNAL BOOLEAN PROCEDURE EXT_FACE(ITEMVAR B);
BEGIN "EXT FACE"
SET LSET;ITEMVAR L1,L2,P,F;

TYPE "EXT_FACE - ENTERED" EOM;
∀ F|FACE⊗B≡F DO
BEGIN "COLLECT"
  ∀ P|CORNER⊗F≡P ∧ (LENGTH(ENDPT`P ∩ BOUNDARY⊗F)=1) DO
	LSET←LSET∪(ENDPT`P ∩ BOUNDARY⊗F);
  IF LENGTH(LSET)=2
  THEN BEGIN
	L1←LOP(LSET);
	L2←COP(LSET);
	IF VERT(L1) ∧ VERT(L2)
	THEN TYPE TAB&"EXTEND "&PRINTNAME(L1)&
		" "&PRINTNAME(L2)&" TO BASE" EOM;
	END;
  END "COLLECT";
TYPE TAB&"NOTHING HAPPENED" EOM;
RETURN(FALSE);
END "EXT FACE";

α	ADDCORNER
This procedure adds a corner at the intersection of
two dangling face boundary lines, subject to some
reasonableness conditions - to keep the behavior conservative;

INTERNAL BOOLEAN PROCEDURE ADDCORNER(ITEMVAR B);
BEGIN "ADDCORNER"
	SET SX,SU,SV,SW;
	INTEGER ITEMVAR L;
	INTEGER N;
	REAL ITEMVAR L1,L2;
	ITEMVAR R,C,F;
	SAFE REAL ARRAY ITEMVAR P,V,V1,V2,VV2,VV1;
	LABEL LAB1;
	BOOLEAN BV1,BV2;

TYPE "ADDCORNER - ENTERED" EOM;
SU←PHI;
∀ F |FACE⊗B≡F DO
BEGIN
	SV←BOUNDARY⊗F;
	∀ P|CORNER⊗F≡P DO
	IF LENGTH((ENDPT`P)∩SV)=1
		THEN PUT F IN SU;
	END;
IF SU=PHI
THEN BEGIN
	TYPE TAB&"NO INCOMPLETE FACES FOR "&PRINTNAME(B) EOM;
	SU←SV←SW←SX←PHI;
	RETURN (FALSE);
	END;


α temporarily, to be conservative, we will only fix faces where there
are only 2 incomplete edges that can be extended to add a corner.;

LAB1:
∀ F| FεSU DO
BEGIN
	SV←BOUNDARY⊗F;
	N←0;
	∀ P|CORNER⊗F≡P DO
	IF LENGTH((ENDPT`P)∩SV)=1
	THEN  N←N+1;
	IF N≠2 ∧ N≠4
	THEN BEGIN
		TYPE TAB&"COMPLETION FOR FACE "&
		PRINTNAME(F)&" ON BODY "&PRINTNAME(B)&" TOO COMPLEX." EOM;
		REMOVE F FROM SU;
		END;
	END;

IF SU=PHI
THEN BEGIN
	SU←SW←SV←SX←PHI;
	RETURN (FALSE);
	END;

∀ F|FεSU DO
BEGIN "ADD"
	BV1←BV2←FALSE;
	SX←CORNER⊗F;
	SV←BOUNDARY⊗F;
	SW←PHI;
	∀ V|VεSX DO
	IF LENGTH((ENDPT`V)∩SV)=1
	THEN PUT V IN SW;
	∀ V1,V2|V1εSW ∧ V2εSW ∧ (V1≠V2) DO
	BEGIN "CORNER"
		LABEL LAB2,LAB3;
		L1←COP((ENDPT`V1)∩SV);
		L2←COP((ENDPT`V2)∩SV);
		VV1←COP(ENDPT⊗L1-{V1});
		VV2←COP(ENDPT⊗L2-{V2});

		IF (ENDPT⊗L1∩ENDPT⊗L2 ≠PHI)
		THEN GO TO LAB2;
		IF PARALLEL(L1,L2)
		THEN GO TO LAB2;
		IF LENGTH(ENDPT`V1∩LINE⊗B)>1
		THEN BEGIN
			BV1←TRUE;
			GO TO LAB3;
			END;
		IF LENGTH(ENDPT`V2∩LINE⊗B)>1
		THEN BEGIN
			BV2←TRUE;
			GO TO LAB3;
			END;

		TYPE TAB&"TRYING "&PRINTNAME(F) EOM;
		P←XPOINT(L1,VV1,L2,VV2);
		PUT P IN NEWPOINTS;
β	DPYINFO("NEW POINT");
β	DPYPT(P);

		IF	DIST(V1,P)>ADCOR1*DIST(V1,VV1) ∨
			DIST(V2,P)>ADCOR1*DIST(V2,VV2) ∨
			(DIST(VV1,P)<DIST(V1,P)) ∨
			(DIST(VV2,P)<DIST(V2,P))
		THEN BEGIN
			TYPE TAB&"NEW POINT REMOVED #1" EOM;
			REMOVE P FROM NEWPOINTS;
			DELETE (P);
			GO TO LAB2;
			END;

		∀ C|CORNER⊗F≡C ∧ CεNEWPOINTS DO
		IF DIST(P,C)<ADCOR2
		THEN BEGIN
			TYPE TAB&"NEW POINT REMOVED #2" EOM;
			DELETE(P);
			P←C;
			DONE;
			END;

LAB3:		IF BV1
		THEN P←V1
		ELSE IF BV2
		     THEN P←V2;

		ERASE POINT⊗B≡V1;
		ERASE POINT⊗B≡V2;
		ERASE ENDPT⊗L1≡V1;
		ERASE ENDPT⊗L2≡V2;
		MAKE POINT⊗B≡P;
		MAKE ENDPT⊗L1≡P;
		MAKE ENDPT⊗L2≡P;

		∀ R|CORNER⊗R≡V1 ∧ FACE⊗B≡R DO
		BEGIN
			ERASE CORNER⊗R≡V1;
			MAKE CORNER⊗R≡P;
			END;

		∀ R|CORNER⊗R≡V2 ∧ FACE⊗B≡R DO
		BEGIN
			ERASE CORNER⊗R≡V2;
			MAKE CORNER⊗R≡P;
			END;

		SU←SV←SW←SX←PHI;
		RETURN (TRUE);
LAB2:		END "CORNER";
	END "ADD";
	SU←SV←SW←SX←PHI;
	TYPE TAB&"NOTHING HAPPENED" EOM;
	RETURN (FALSE);
END "ADDCORNER";

α	ADDFACE
Sometimes a face has no visible boundaries, but is
bounded by two complete faces.  By adding two lines
parallel to the inside boundaries of the two bounding
faces, the missing face is added.

      \--------------\
      |\	      \
      | \ P	L1     \ 
      |  |--------------\ P1
      |  |		.
      |  | L2		. ← new line (LA)
      \  |		.
       \ |		.
        \| . . . . . . .*  ← point of intersection of two added lines
        P2	↑
	    new line (LB)
;

INTERNAL BOOLEAN PROCEDURE ADDFACE(ITEMVAR B);
BEGIN "ADD FACE"
SET FSET;
ITEMVAR X,P,P1,P2,PN,L,L1,L2,LA,LB,F,FN,F1,F2;

BOOLEAN PROCEDURE COMP(ITEMVAR F);
BEGIN "COMPLETE"
SET S;ITEMVAR P;
S←BOUNDARY⊗F;
∀ P|CORNER⊗F≡P DO IF LENGTH(ENDPT`P ∩ S)=1 THEN RETURN(FALSE);
RETURN(TRUE);
END "COMPLETE";

TYPE "ADDFACE - ENTERED" EOM;
FSET←FACE⊗B;
IF LENGTH(FSET)=2
THEN BEGIN "ADD 1"
  F1←LOP(FSET);
  F2←COP(FSET);
  TYPE TAB&"FACES "&PRINTNAME(F1)&"  "&PRINTNAME(F2) EOM;
  IF COMP(F1) ∧ COMP(F2)
  THEN ∀ P|CORNER⊗F1≡P ∧ FLAVOR⊗P≡GOODY DO
    BEGIN "ADD 2"
	ASSIGN L1,L2|BOUNDARY⊗F1≡L1 ∧ BOUNDARY⊗F2≡L2 ∧
		(L1≠L2) ∧ ENDPT⊗L1≡P ∧ ENDPT⊗L2≡P HOLDS;
	P1←COP(ENDPT⊗L1 - {P});
	P2←COP(ENDPT⊗L2 - {P});
	PN←XPOINT(L1,P2,L2,P1);
	PUT PN IN NEWPOINTS;
β	DPYPT(PN);
	LA←NEW(0.0);NEW_PNAME(LA,GENSYM(NEWL));
	MAKE ENDPT⊗LA≡PN;
	MAKE ENDPT⊗LA≡P1;
	LB←NEW(0.0);NEW_PNAME(LB,GENSYM(NEWL));
	MAKE ENDPT⊗LB≡PN;
	MAKE ENDPT⊗LB≡P2;
	FN←NEW(SIZE4);NEW_PNAME(FN,GENSYM(NEWF));
	MAKE BOUNDARY⊗FN≡L1;
	MAKE BOUNDARY⊗FN≡L2;
	MAKE BOUNDARY⊗FN≡LA;
	MAKE BOUNDARY⊗FN≡LB;
	MAKE CORNER⊗FN≡P1;
	MAKE CORNER⊗FN≡P2;
	MAKE CORNER⊗FN≡PN;
	MAKE CORNER⊗FN≡P;
	MAKE LINE⊗B≡LA;
	MAKE LINE⊗B≡LB;
	MAKE POINT⊗B≡PN;
	MAKE FACE⊗B≡FN;
	RETURN(TRUE);
	END "ADD 2";
  END "ADD 1";

TYPE TAB&"NOTHING HAPPENED" EOM;
RETURN(FALSE);
END "ADD FACE";

α	CLEAN
clean up the data structure by killing all associations,
local and global items;
INTERNAL PROCEDURE CLEAN;
BEGIN "CLEAN"
	ITEMVAR X,Y,Z;
	INTEGER I,FIRST,LAST;

ITEMN←NEW;
FIRST←CVN(ITEM1);
LAST←CVN(ITEMN);
FOR I←FIRST STEP 1 UNTIL LAST DO
BEGIN "TRIPLES"
	X←CVI(I);
	ERASE X⊗ANY≡ANY;
	ERASE ANY⊗X≡ANY;
	ERASE ANY⊗ANY≡X;
	END "TRIPLES";
GLOBAL ERASE ANY⊗SCENE≡ANY;
FOR I←FIRST STEP 1 UNTIL LAST DO
BEGIN "ITEMS"
	X←CVI(I);
	DELETE(X);
	END "ITEMS";
TYPE ↓&↓&↓&TAB&TAB&"READY FOR NEW SCENE"&↓&↓&↓ EOM;
END "CLEAN";



END "SEG2";